package org.codingq92.project.bio_chat.server;

import org.codingq92.project.bio_chat.util.Constants;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.Socket;
import java.util.Collection;

/**
 * 聊天室服务端
 *
 * @author: CodingQ92
 * @date: 2025/6/24 23:13
 */
public class ChatServerHandler extends Thread {
    private final Socket socket;

    public ChatServerHandler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        DataInputStream dis = null;
        try {
            InputStream inputStream = socket.getInputStream();
            dis = new DataInputStream(inputStream);
            // 循环读取消息
            while (true) {
                // 消息标志 0:用户上线 1:群发消息 2:私聊消息 3:@消息 4:用户下线
                int flag = dis.readInt();
                if (Constants.LOGIN == flag) {
                    String name = dis.readUTF();
                    ChatServer.onlineUsers.put(socket, name);
                    System.out.println(name + "(" + socket.getRemoteSocketAddress() + ")加入聊天室!!!" + Constants.getTime());
                }
                noticeMsg(flag, dis);
            }
        } catch (Exception e) {
            System.out.println(socket.getRemoteSocketAddress() + ">>>下线了!!!" + Constants.getTime());
            ChatServer.onlineUsers.remove(socket);
            // 需要通知聊天室更新在线人数
            try {
                noticeMsg(Constants.LOGIN, dis);
            } catch (Exception e1) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 通知聊天室
     *
     * @param flag 消息标志 0:用户上线 1:群发消息 2:私聊消息 3:@消息 4:用户下线
     * @param dis
     */
    private void noticeMsg(int flag, DataInputStream dis) {
        try {
            String msg = "";
            if (Constants.LOGIN == flag) {
                System.out.println("开始通知客户端更新在线人数～" + ChatServer.onlineUsers.size());
                if (!ChatServer.onlineUsers.isEmpty()) {
                    Collection<String> values = ChatServer.onlineUsers.values();
                    StringBuilder stringBuilder = new StringBuilder();
                    for (String name : values) {
                        stringBuilder.append(name).append(Constants.SPLIT);
                    }
                    msg = stringBuilder.substring(0, stringBuilder.lastIndexOf(Constants.SPLIT));
                }
                System.out.println("最新在线人员名单: " + msg + " " + Constants.getTime());
                forwardingGroupMsg(flag, msg);
            } else if (Constants.GROUP_MSG == flag) {
                msg = dis.readUTF();
                System.out.println("收到群聊消息：" + msg + " " + Constants.getTime());
                forwardingGroupMsg(flag, msg);
            } else if (Constants.PRIVATE_MSG == flag) {
                String username = dis.readUTF();
                msg = dis.readUTF();
                System.out.println(username + "(" + socket.getRemoteSocketAddress() + ")发来私聊" + username + "的消息：" + msg + " " + Constants.getTime());
                forwardingPrivateMsg(username, msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 给指定用户发送消息
     *
     * @param username 指定用户
     * @param msg      消息内容
     */
    private void forwardingPrivateMsg(String username, String msg) {
        try {
            // 先给自己发送一条私聊消息
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            dos.writeInt(Constants.PRIVATE_MSG);
            dos.writeUTF(msg);
            dos.flush();
            // 筛选给私聊对象发送
            for (Socket socket : ChatServer.onlineUsers.keySet()) {
                String currentUser = ChatServer.onlineUsers.get(socket);
                if (!currentUser.equals(username)) {
                    continue;
                }
                dos = new DataOutputStream(socket.getOutputStream());
                dos.writeInt(Constants.PRIVATE_MSG);
                dos.writeUTF(msg);
                dos.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 给所有在线用户发送消息
     *
     * @param flag 消息标志 0:用户上线 1:群发消息 2:私聊消息 3:@消息 4:用户下线
     * @param msg  消息内容
     */
    private void forwardingGroupMsg(int flag, String msg) {
        for (Socket socket : ChatServer.onlineUsers.keySet()) {
            try {
                DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                dos.writeInt(flag);
                dos.writeUTF(msg);
                dos.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
